<template>
  <div class="map-container">
    <!-- 地图容器 -->
    <div id="baidu-map" class="map"></div>
    <!-- 操作面板 -->
    <div class="j-top-box">
      <div class="j-top">
        <div class="j-top-left">
          <span>轨迹回放</span>
          <span style="margin-left: 15px; color: #008e00">汉兰达</span>
          <span style="color: #008e00">（IMEI:85614542978792）</span>
          <el-input
            v-model="imei"
            class="w-50 m-2"
            style="width: 240px"
            size="small"
            placeholder="请输入设备IMEI"
          />
          <div style="margin-left: 10px">
            <el-select v-model="timeSelect" size="small" style="width: 80px">
              <el-option :value="1" label="上周">上周</el-option>
              <el-option :value="2" label="本周">本周</el-option>
              <el-option :value="3" label="前天">前天</el-option>
              <el-option :value="4" label="昨天">昨天</el-option>
              <el-option :value="5" label="今天">今天</el-option>
              <el-option :value="6" label="最近七天">最近七天</el-option>
              <el-option :value="7" label="自定义">自定义</el-option>
            </el-select>
          </div>
          <div class="range-control">
            <el-date-picker
              v-model="dateRange"
              size="small"
              type="datetimerange"
              range-separator="至"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              value-format="YYYY-MM-DD HH:mm:ss"
              :unlink-panels="true"
              style="width: 100%"
              @change="onRangeChange"
            />
          </div>
          <el-button type="primary" style="margin-left: 20px" size="small" @click="handleQuery">
            查询
          </el-button>
          <el-button style="margin-left: 10px" size="small" @click="handleQuery">重置</el-button>
        </div>
        <el-button style="margin-right: 5px" @click="startCorrection">实时跟踪</el-button>
        <el-button style="margin-right: 5px" @click="toggleOverviewRoute">轨迹总览</el-button>
        <el-button style="margin-right: 10px" @click="trajectoryDetails">轨迹明细</el-button>
      </div>
      <div class="j-top1-box">
        <div class="j-top1">
          <!-- <div class="btn">
            <el-icon color="#fff" size="22"><CaretRight /></el-icon>
          </div> -->
          <div v-if="isPlay == 1">
            <el-image
              src="/src/assets/img/11.png"
              style="width: 35px; height: 35px"
              @click="playBtn(1)"
            ></el-image>
          </div>
          <div v-if="isPlay == 2">
            <el-image
              src="/src/assets/img/10.png"
              style="width: 35px; height: 35px"
              @click="playBtn(2)"
            ></el-image>
          </div>
          <div v-if="isPlay == 3">
            <el-image
              src="/src/assets/img/11.png"
              style="width: 35px; height: 35px"
              @click="playBtn(3)"
            ></el-image>
          </div>
          <div style="margin-left: 10px">
            <div class="progress-control">
              <input
                id="progress"
                v-model="currentPointIndex"
                type="range"
                min="0"
                :max="pathPoints.length - 1"
                class="progress-slider"
                :disabled="!isReady"
                @input="handleProgressChange"
              />
              <span>{{ Math.round((currentPointIndex / (pathPoints.length - 1)) * 100) }}%</span>
            </div>

            <div class="speed-control">
              <!-- <label for="speed" style="font-size: 12px">2025-8-25 17:32:08</label> -->
              <el-text>{{ drivingTime }}</el-text>
              <input
                id="speed"
                v-model="animationSpeed"
                type="range"
                min="1"
                max="10"
                class="speed-slider"
              />
              <span>{{ animationSpeed }}x</span>
            </div>
          </div>
          <el-button
            icon="RefreshRight"
            style="margin-left: 10px"
            @click="resetAnimation"
          ></el-button>

          <el-text style="margin-left: 30px">总里程：13.04 km 速度：21KM/H</el-text>
        </div>
        <div style="display: flex; align-items: center; margin-right: 30px">
          <div>
            <el-text>
              <el-icon color="#409EFF">
                <Location />
              </el-icon>
              卫星
            </el-text>
          </div>
          <div>
            <el-text>
              <el-icon color="#E6A23C">
                <Location />
              </el-icon>
              基站
            </el-text>
          </div>
          <div>
            <el-text>
              <el-icon color="#67C23A">
                <Location />
              </el-icon>
              WIFI
            </el-text>
          </div>
        </div>
      </div>
    </div>
    <div
      class="track-panel"
      :class="{ hidden: trackPanelHidden, resizing: isResizing }"
      :style="{ height: trackPanelHeight + 'px' }"
    >
      <el-card class="track-card">
        <template #header>
          <div class="card-header">
            <span class="title">轨迹点列表</span>
            <div class="controls">
              <el-button icon="Close" size="small" circle @click="hideTrackPanel" />
            </div>
          </div>
        </template>
        <div class="track-list">
          <el-table :data="trackList" :height="trackPanelHeight - 80" stripe>
            <el-table-column prop="index" align="center" label="序号" width="80" />
            <el-table-column prop="createTime" align="center" width="180" label="时间" />
            <el-table-column prop="sourceCoord" align="center" width="180" label="纬度/经度" />
            <!-- <el-table-column prop="lat" label="纬度" /> -->
            <el-table-column prop="speed" align="center" width="120" label="速度(km/h)" />
            <el-table-column prop="direction" align="center" width="120" label="方向角度" />
            <el-table-column prop="mileage" align="center" label="里程(km)" width="120" />
            <el-table-column
              prop="warn"
              align="center"
              label="报警信息"
              width="220"
              show-overflow-tooltip
            />
            <el-table-column
              prop="position"
              align="center"
              label="位置信息"
              show-overflow-tooltip
            />
          </el-table>
        </div>
      </el-card>
      <div class="resize-handle" @mousedown="startResize"></div>
    </div>
    <!-- 悬浮显示按钮 -->
    <div v-show="trackPanelHidden" class="floating-btn" @click="showTrackPanel">
      <el-button type="primary" icon="List" circle />
    </div>
    <!-- 控制面板 -->
    <!-- <div class="control-panel">

      <h3>路书路径动画演示</h3>

      <div class="overview-control">
        <button :disabled="!isReady" class="overview-btn" @click="toggleOverviewRoute">
          <i class="fas" :class="showOverviewRoute ? 'fa-eye-slash' : 'fa-eye'"></i>
          {{ showOverviewRoute ? "隐藏总览路线" : "显示总览路线" }}
        </button>
      </div>

      <div class="progress-control">
        <label for="progress">进度：</label>
        <input
          id="progress"
          v-model="currentPointIndex"
          type="range"
          min="0"
          :max="pathPoints.length - 1"
          class="progress-slider"
          :disabled="!isReady"
          @input="handleProgressChange"
        />
        <span>{{ Math.round((currentPointIndex / (pathPoints.length - 1)) * 100) }}%</span>
      </div>

      <div class="button-group">
        <button
          :disabled="isAnimating || !isReady"
          class="control-btn start-btn"
          @click="startAnimation"
        >
          <i class="fas fa-play"></i>
          开始
        </button>
        <button
          :disabled="!isAnimating || isPaused || !isReady"
          class="control-btn pause-btn"
          @click="pauseAnimation"
        >
          <i class="fas fa-pause"></i>
          暂停
        </button>
        <button
          :disabled="!isAnimating || !isPaused || !isReady"
          class="control-btn resume-btn"
          @click="resumeAnimation"
        >
          <i class="fas fa-play"></i>
          继续
        </button>
        <button :disabled="!isReady" class="control-btn reset-btn" @click="resetAnimation">
          <i class="fas fa-redo"></i>
          重置
        </button>
      </div>

      <div class="speed-control">
        <label for="speed">速度：</label>
        <input
          id="speed"
          v-model="animationSpeed"
          type="range"
          min="1"
          max="10"
          class="speed-slider"
        />
        <span>{{ animationSpeed }}x</span>
      </div>
    </div> -->
  </div>
</template>

<script setup>
import { ref, onMounted, watch, computed, nextTick } from "vue";
import carIcon from "@/assets/img/07.png";
import qiIcon from "@/assets/img/08.png";
import zhiIcon from "@/assets/img/09.png";
import { ElLoading, ElMessage } from "element-plus";
import DeviceApi from "@/api/system/device.api";
import { useRoute } from "vue-router";
import axios from "axios";
const route = useRoute();
console.log("目标页面参数", route.query.id);

// 状态管理
const map = ref(null);
const marker = ref(null);
const polyline = ref(null);
// 新增：日期时间范围（与 el-date-picker 绑定）
const dateRange = ref([]);
const overviewPolyline = ref(null); // 总览路线
const startMarker = ref(null); // 起点标记
const endMarker = ref(null); // 终点标记
const infoWindow = ref(null);
const isAnimating = ref(false);
const isPaused = ref(false);
const isReady = ref(false);
const showOverviewRoute = ref(false); // 是否显示总览路线
const animationSpeed = ref(3);
const currentPointIndex = ref(0);
const animationInterval = ref(null);
const trackPanelHeight = ref(300); // 轨迹面板高度
const isResizing = ref(false); // 是否正在调整大小
const trackPanelHidden = ref(true); //轨迹面板是否隐藏
const trackList = ref([]); //轨迹表格

const previousAngle = ref(0);
const queryParams = ref({
  pageNum: 1,
  pageSize: 99999,
  clientId: "76",
  startTime: "",
  endTime: "",
});
const imei = ref("");
const correctedPoints = ref([]);
const showResult = ref(false);
const drivingTime = ref("");
const timeSelect = ref(5);
// 路径点坐标（示例路径）
// const pathPoints = [
//   { lng: 116.395, lat: 39.918 }, // 天安门附近（起点）
//   { lng: 116.405, lat: 39.918 },
//   { lng: 116.415, lat: 39.915 },
//   { lng: 116.425, lat: 39.91 },
//   { lng: 116.435, lat: 39.905 },
//   { lng: 116.445, lat: 39.9 },
//   { lng: 116.455, lat: 39.895 },
//   { lng: 116.465, lat: 39.89 },
//   { lng: 116.475, lat: 39.885 },
//   { lng: 116.485, lat: 39.88 }, // 接近天坛公园
//   { lng: 116.495, lat: 39.875 },
//   { lng: 116.5, lat: 39.87 },
//   { lng: 116.505, lat: 39.865 },
//   { lng: 116.515, lat: 39.86 },
//   { lng: 116.525, lat: 39.855 }, // 终点
// ];
const pathPoints1 = [];
let pathPoints = [];
// pathPoints1 = [
//   {
//     index: 1,
//     time: "2025-08-26 16:27:03",
//     lng: 119.43185515441223,
//     lat: 35.99974558101032,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,电脑办公设备东南96米",
//     speed: 0,
//     direction: "正北",
//     mileage: 0,
//     altitude: 139,
//     acc: 2,
//     warn: "正常",
//     battery: "开",
//     signal: 25,
//   },
//   {
//     index: 2,
//     time: "2025-08-26 16:27:47",
//     lng: 119.43169239948976,
//     lat: 35.99965550347208,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,电脑办公设备东南92米",
//     speed: 0,
//     direction: "正北",
//     mileage: 0,
//     altitude: 147,
//     acc: 3,
//     warn: "正常",
//     battery: "开",
//     signal: 22,
//   },
//   {
//     index: 3,
//     time: "行驶中",
//     lng: 119.43156260695822,
//     lat: 35.99965946012596,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,万家共享(东武街店)附近15米",
//     speed: 5.9,
//     direction: "东偏北3度",
//     mileage: 0,
//     altitude: 118,
//     acc: 2,
//     warn: "正常",
//     battery: "开",
//     signal: 23,
//   },
//   {
//     index: 4,
//     time: "行驶中",
//     lng: 119.43156260557568,
//     lat: 35.99965145808463,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,万家共享(东武街店)附近15米",
//     speed: 5,
//     direction: "南偏东29度",
//     mileage: 0,
//     altitude: 119,
//     acc: 2,
//     warn: "正常",
//     battery: "开",
//     signal: 23,
//   },
//   {
//     index: 5,
//     time: "行驶中",
//     lng: 119.43131899608592,
//     lat: 35.99968038019562,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,电脑办公设备南71米",
//     speed: 5.9,
//     direction: "西偏南38度",
//     mileage: 0,
//     altitude: 115,
//     acc: 2,
//     warn: "正常",
//     battery: "开",
//     signal: 27,
//   },
//   {
//     index: 6,
//     time: "2025-08-26 16:28:42",
//     lng: 119.43128603811085,
//     lat: 35.99962335391429,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,电脑办公设备南78米",
//     speed: 0,
//     direction: "南偏东4度",
//     mileage: 0,
//     altitude: 107,
//     acc: 2,
//     warn: "正常",
//     battery: "开",
//     signal: 27,
//   },
//   {
//     index: 7,
//     time: "行驶中",
//     lng: 119.43138381284376,
//     lat: 35.99921228372987,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,万家共享(东武街店)南71米",
//     speed: 5.3,
//     direction: "南偏东24度",
//     mileage: 0.1,
//     altitude: 91,
//     acc: 2,
//     warn: "正常",
//     battery: "开",
//     signal: 31,
//   },
//   {
//     index: 8,
//     time: "2025-08-26 16:29:37",
//     lng: 119.43144867498657,
//     lat: 35.999008254437314,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,万家共享(东武街店)南99米",
//     speed: 0,
//     direction: "南偏东6度",
//     mileage: 0.1,
//     altitude: 84,
//     acc: 2,
//     warn: "正常",
//     battery: "开",
//     signal: 29,
//   },
//   {
//     index: 9,
//     time: "2025-08-26 16:30:37",
//     lng: 119.43141575942398,
//     lat: 35.99919529063338,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,万家共享(东武街店)南73米",
//     speed: 0,
//     direction: "北偏东3度",
//     mileage: 0.1,
//     altitude: 85,
//     acc: 2,
//     warn: "正常",
//     battery: "开",
//     signal: 31,
//   },
//   {
//     index: 10,
//     time: "行驶中",
//     lng: 119.43144878956535,
//     lat: 35.99967142366728,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,万家共享(东武街店)附近8米",
//     speed: 6.1,
//     direction: "东偏北7度",
//     mileage: 0.2,
//     altitude: 84,
//     acc: 2,
//     warn: "正常",
//     battery: "开",
//     signal: 26,
//   },
//   {
//     index: 11,
//     time: "行驶中",
//     lng: 119.43154663942661,
//     lat: 35.999700465075335,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,电脑办公设备东南78米",
//     speed: 5.7,
//     direction: "正东北",
//     mileage: 0.2,
//     altitude: 85,
//     acc: 2,
//     warn: "正常",
//     battery: "开",
//     signal: 21,
//   },
//   {
//     index: 12,
//     time: "2025-08-26 16:31:24",
//     lng: 119.43156261335253,
//     lat: 35.99969646956684,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,电脑办公设备东南79米",
//     speed: 0,
//     direction: "东偏北7度",
//     mileage: 0.2,
//     altitude: 85,
//     acc: 2,
//     warn: "正常",
//     battery: "开",
//     signal: 21,
//   },
//   {
//     index: 13,
//     time: "2025-08-26 16:32:41",
//     lng: 119.43166045618125,
//     lat: 35.999688501040595,
//     position: "山东省潍坊市诸城市密州街道东郊街15号朝阳公馆内,电脑办公设备东南86米",
//     speed: 0,
//     direction: "东偏南36度",
//     mileage: 0.2,
//     altitude: 91,
//     acc: 3,
//     warn: "正常",
//     battery: "开",
//     signal: 21,
//   },
// ]; // 轨迹列表数据

// 计算当前点
const currentPoint = computed(() => {
  return pathPoints[currentPointIndex.value];
});
const hideTrackPanel = () => {
  trackPanelHidden.value = true;
};

const showTrackPanel = () => {
  trackPanelHidden.value = false;
};

const isPlay = ref(1);
function playBtn(index) {
  if (currentPointIndex.value >= pathPoints.length - 1) {
    resetAnimation();
    startAnimation();
    //在终点
    isPlay.value = 2;
  } else {
    if (isPlay.value == 1) {
      startAnimation();
      isPlay.value = 2;
    } else if (isPlay.value == 2) {
      pauseAnimation();
      isPlay.value = 3;
    } else if (isPlay.value == 3) {
      resumeAnimation();
      isPlay.value = 2;
    }
  }
}
// 还原拖拽拉伸逻辑
let startY = 0;
let startHeight = 0;
const MIN_HEIGHT = 200;
const MAX_HEIGHT = 600;

const onMouseMove = (e) => {
  const delta = e.clientY - startY;
  // handle 在 panel 顶部，向上拖动（delta < 0）应增大高度
  let newHeight = startHeight - delta;
  newHeight = Math.max(MIN_HEIGHT, Math.min(MAX_HEIGHT, newHeight));
  trackPanelHeight.value = newHeight;
};

const stopResize = () => {
  if (!isResizing.value) return;
  isResizing.value = false;
  document.body.classList.remove("resizing");
  window.removeEventListener("mousemove", onMouseMove);
  window.removeEventListener("mouseup", stopResize);
};

const startResize = (e) => {
  e.preventDefault();
  isResizing.value = true;
  document.body.classList.add("resizing");
  startY = e.clientY;
  startHeight = trackPanelHeight.value;
  window.addEventListener("mousemove", onMouseMove);
  window.addEventListener("mouseup", stopResize);
};

onBeforeUnmount(() => {
  stopResize();
});

const getLocusList = async () => {
  const loading = ElLoading.service({
    lock: true,
    text: "Loading",
    background: "rgba(0, 0, 0, 0.7)",
  });
  try {
    queryParams.value.clientId = route.query.id;
    const res = await DeviceApi.getLocus(queryParams.value);
    console.log("轨迹列表", res.data.data.records);
    trackList.value = res.data.data.records;
    if (res.data.data.records.length > 0) {
      drivingTime.value = res.data.data.records[0].createTime;
    }
    pathPoints = res.data.data.records || [];
    if (pathPoints.length <= 1) {
      console.error("该时间段暂无轨迹");
    }
  } catch (e) {
    console.error("获取轨迹失败", e);
    pathPoints = [];
  } finally {
    loading.close();
  }
};
const processTime = ref(0);
const correctedTrack = ref(null);
// 开始轨迹纠偏
const startCorrection = async () => {
  if (pathPoints.length < 2) return;

  const startTime = performance.now();
  // correctionStatus.value = "正在进行轨迹纠偏...";
  showResult.value = true;

  try {
    // 准备请求参数
    // const pointList = pathPoints
    //   .map((point) => {
    //     return `${point.lng},${point.lat},bd09ll`;
    //   })
    //   .join(";");
    const pointList = [];

    pathPoints.forEach((item) => {
      console.log(item.createTime);
      const formattedStr = item.createTime.replace(" ", "T");
      const date = new Date(formattedStr);
      const locTimeSec = Math.floor(date.getTime() / 1000);
      pointList.push({
        loc_time: locTimeSec,
        latitude: item.lat.toFixed(6),
        longitude: item.lng.toFixed(6),
        coord_type_input: "bd09ll",
      });
    });

    // 生成签名

    // 构建请求参数
    const params = {
      pointList: JSON.stringify(pointList),
    };
    // const sn = generateSignature(params);

    const response = await DeviceApi.proofreadingBias(params);
    console.log("请求参数", response.data.data.points);

    // 处理响应结果
    if (response.data.code == 0 && response.data.data) {
      // correctionStatus.value = "ncorrect成功";
      // 处理ncorrectedPoints后的点
      correctedPoints.value = response.data.data.points.map(
        (p) => new BMap.Point(p.longitude, p.latitude)
      );
      // 绘制ncorrectedTrack后的轨迹
      drawCorrectedTrack();
    } else {
      // correctionStatus.value = `ncorrect失败: ${response.data.message || "未知错误"}`;
      console.error("轨迹ncorrect失败:", response.data);
    }
  } catch (error) {
    // correctionStatus.value = `请求错误: ${error.message}`;
    console.error("调用ncorrectAPI出错:", error);
  } finally {
    // 计算处理时间
    processTime.value = Math.round(performance.now() - startTime);
  }
};

// 绘制ncorrected后的轨迹
const drawCorrectedTrack = () => {
  // 清除已有的ncorrected轨迹
  if (correctedTrack.value) {
    map.value.removeOverlay(correctedTrack.value);
  }

  // 创建ncorrected后的轨迹线（蓝色）
  correctedTrack.value = new BMap.Polyline(correctedPoints.value, {
    strokeColor: "#1890ff",
    strokeWeight: 4,
    strokeOpacity: 0.9,
  });

  // 添加到地图
  map.value.addOverlay(correctedTrack.value);
};

// 生成百度API签名
const generateSignature = (params) => {
  // 1. 按参数名升序排序
  const sortedParams = Object.keys(params)
    .sort()
    .reduce((obj, key) => {
      obj[key] = params[key];
      return obj;
    }, {});

  // 2. 拼接为key=value&key=value形式
  let queryString = "";
  Object.entries(sortedParams).forEach(([key, value], index) => {
    queryString += `${key}=${value}`;
    if (index < Object.entries(sortedParams).length - 1) {
      queryString += "&";
    }
  });

  // 3. 拼接路径和SK并计算MD5
  const signatureStr = `/rectify/v1/track?${queryString}`;
  return md5(signatureStr);
};

function trajectoryDetails() {
  trackPanelHidden.value = !trackPanelHidden.value;
}
// 初始化地图
const initMap = () => {
  // 兼容 BMapGL 与 BMap
  if (!window.BMap && window.BMapGL) {
    window.BMap = window.BMapGL;
  }
  // 确保百度地图API已加载
  if (!window.BMap && !window.BMapGL) {
    console.error("百度地图API未加载");
    return;
  }

  // 创建地图实例
  map.value = new BMap.Map("baidu-map");

  // // 切换为平面视角（取消倾斜与旋转）
  // if (map.value && typeof (map.value ).setTilt === "function") {
  //   (map.value ).setTilt(0);
  // }
  // if (map.value && typeof (map.value ).setHeading === "function") {
  //   (map.value ).setHeading(0);
  // }

  // 设置中心点和缩放级别（显示整个路径的合适级别）

  console.log("设置中心点", pathPoints);
  if (pathPoints.length > 0) {
    const centerPoint = new BMap.Point(pathPoints[0].lng, pathPoints[0].lat);
    map.value.centerAndZoom(centerPoint, 18);
  } else {
    const centerPoint = new BMap.Point(116.404, 39.915);
    map.value.centerAndZoom(centerPoint, 18);
  }

  // 禁用3D视角和倾斜功能
  disable3DMode();

  // 应用平面样式
  applyFlatStyle();
  // 添加地图控件
  map.value.addControl(
    new BMap.NavigationControl({
      // 控件的位置
      anchor: BMAP_ANCHOR_TOP_LEFT, // 右下角

      // 控件的偏移量
      offset: new BMap.Size(20, 180), // 向右偏移20px，向上偏移80px

      // 控件的样式
      type: BMAP_NAVIGATION_CONTROL_SMALL, // 小型控件（仅包含缩放按钮）
      // type: BMAP_NAVIGATION_CONTROL_ZOOM, // 仅包含缩放按钮的样式
      // type: BMAP_NAVIGATION_CONTROL_LARGE, // 包含平移和缩放按钮的大型控件
    })
  );
  map.value.addControl(new BMap.ScaleControl());
  // map.value.addControl(new BMap.OverviewMapControl());

  // 允许鼠标滚轮缩放
  map.value.enableScrollWheelZoom(true);

  // 初始化信息窗口
  initInfoWindow();

  // 初始化起点和终点标记
  initStartAndEndMarkers();
  if (showOverviewRoute.value) {
    initOverviewPolyline();
  }
  // 初始化总览路线

  // 初始化移动标记
  initMarker();

  // 初始化当前绘制路线
  initPolyline();

  // 调整地图以显示整个路线
  adjustMapToShowAllRoute();

  // 标记地图已准备就绪
  isReady.value = true;

  // 轨迹路线绘制完成后，设置播放状态为1（准备播放）
  isPlay.value = 1;
  showResult.value = false;
};

// 禁用3D模式相关功能
const disable3DMode = () => {
  if (!map.value) return;

  // 禁用地图倾斜
  if (map.value.disableTilt) {
    map.value.disableTilt();
  }

  // 禁用旋转
  if (map.value.disableRotation) {
    map.value.disableRotation();
  }

  // 强制设置为0度倾斜角
  if (map.value.setTilt) {
    map.value.setTilt(0);
  }

  // 确保地图类型为2D
  if (map.value.setMapType) {
    map.value.setMapType(BMap.MapType.MAPTYPE_NORMAL);
  }
};

// 应用平面地图样式
const applyFlatStyle = () => {
  if (!map.value) return;

  // 平面风格配置 - 无3D效果，简化地图元素
  const flatStyle = [
    // {
    //   featureType: "land",
    //   elementType: "all",
    //   stylers: {
    //     color: "#f7f7f7",
    //   },
    // },
    // {
    //   featureType: "road",
    //   elementType: "all",
    //   stylers: {
    //     color: "#ffffff",
    //     weight: 1,
    //     visibility: "on",
    //   },
    // },
    // {
    //   featureType: "highway",
    //   elementType: "all",
    //   stylers: {
    //     color: "#f0f0f0",
    //     weight: 2,
    //   },
    // },
    // {
    //   featureType: "water",
    //   elementType: "all",
    //   stylers: {
    //     color: "#e6f3ff",
    //   },
    // },
    {
      featureType: "building",
      elementType: "all",
      stylers: {
        color: "#e8e8e8",
        visibility: "simplified", // 简化建筑物显示，无3D效果
      },
    },
    // {
    //   featureType: "green",
    //   elementType: "all",
    //   stylers: {
    //     color: "#e5f2e5",
    //   },
    // },
    {
      featureType: "poi",
      elementType: "all",
      stylers: {
        visibility: "simplified", // 简化兴趣点显示
      },
    },
  ];

  // 应用样式
  if (map.value.setMapStyleV2) {
    map.value.setMapStyleV2({ styleJson: flatStyle });
  } else if (map.value.setMapStyle) {
    map.value.setMapStyle({ styleJson: flatStyle });
  } else {
    console.warn("当前百度地图版本不支持自定义样式");
  }
};

// 初始化信息窗口
const initInfoWindow = () => {
  infoWindow.value = new BMap.InfoWindow("", {
    width: 300, // 信息窗口宽度
    height: 200, // 信息窗口高度
    title: "定位信息", // 信息窗口标题
    enableMessage: false, // 不启用信息窗口发送短息功能
  });
};

// 更新信息窗口内容
const updateInfoWindow = (point, index) => {
  if (!infoWindow.value || !point) return;
  drivingTime.value = point.createTime;
  // 格式化坐标信息，保留6位小数
  const content = `
    <div style="padding:0 10px;">
      <span><strong>序号 #${index + 1}</strong></span>
      <div style="display: flex;">
         <div style="width: 70px;">时间:</div><div> ${point.createTime}</div>
        </div>
       <div style="display: flex;">
         <div style="width: 70px;">行驶里程:</div><div> ${point.mileage}KM </div>
        </div>  <div style="display: flex;">
         <div style="width: 70px;">速度:</div><div> ${point.speed}KM/H</div>
        </div>  <div style="display: flex;">
         <div style="width: 70px;">定位地点:</div><div style="flex:1;font-size:12px"> ${point.position}</div>
        </div>
    </div>
  `;

  // 设置信息窗口内容
  infoWindow.value.setContent(content);

  // 在当前点显示信息窗口
  const bmapPoint = new BMap.Point(point.lng, point.lat);
  map.value.openInfoWindow(infoWindow.value, bmapPoint);
};

// 关闭信息窗口
const closeInfoWindow = () => {
  if (infoWindow.value && map.value) {
    map.value.closeInfoWindow(infoWindow.value);
  }
};

// 初始化起点和终点标记
const initStartAndEndMarkers = () => {
  // 起点标记
  const startPoint = new BMap.Point(pathPoints[0].lng, pathPoints[0].lat);
  const startIcon = new BMap.Icon(qiIcon, new BMap.Size(32, 32));
  startMarker.value = new BMap.Marker(startPoint, { icon: startIcon });
  map.value.addOverlay(startMarker.value);

  // 起点信息窗口
  // const startInfoWindow = new BMap.InfoWindow("<p>起点</p>", { width: 80 });
  // startMarker.value.addEventListener("click", () => {
  //   map.value.openInfoWindow(startInfoWindow, startPoint);
  // });

  // 终点标记
  const endPoint = new BMap.Point(
    pathPoints[pathPoints.length - 1].lng,
    pathPoints[pathPoints.length - 1].lat
  );
  const endIcon = new BMap.Icon(zhiIcon, new BMap.Size(32, 32));
  endMarker.value = new BMap.Marker(endPoint, { icon: endIcon });
  map.value.addOverlay(endMarker.value);

  // 终点信息窗口
  // const endInfoWindow = new BMap.InfoWindow("<p>终点</p>", { width: 80 });
  // endMarker.value.addEventListener("click", () => {
  //   map.value.openInfoWindow(endInfoWindow, endPoint);
  // });
};

// 初始化总览路线
const initOverviewPolyline = () => {
  // 转换路径点为BMap.Point对象
  const points = pathPoints.map((point) => new BMap.Point(point.lng, point.lat));

  // // 创建总览折线（虚线样式，与当前绘制路线区分）
  // overviewPolyline.value = new BMap.Polyline(points, {
  //   strokeColor: "#95a5a6",
  //   strokeWeight: 2,
  //   strokeOpacity: 0.6,
  //   strokeStyle: "dashed", // 虚线样式
  //   strokeDasharray: [10, 5], // 虚线间隔
  // });
  // 创建总览折线（虚线样式，与当前绘制路线区分）
  overviewPolyline.value = new BMap.Polyline(points, {
    strokeColor: "#00c220",
    strokeWeight: 4,
    strokeOpacity: 1,
    strokeStyle: "solid", // 实线样式
  });

  // 添加总览折线到地图
  map.value.addOverlay(overviewPolyline.value);
};

// 切换总览路线显示/隐藏
const toggleOverviewRoute = () => {
  showOverviewRoute.value = !showOverviewRoute.value;
  if (showOverviewRoute.value) {
    initOverviewPolyline();
    map.value.addOverlay(overviewPolyline.value);
  } else {
    map.value.removeOverlay(overviewPolyline.value);
  }
};

// 初始化移动标记
const initMarker = () => {
  const startPoint = new BMap.Point(pathPoints[0].lng, pathPoints[0].lat);

  // 创建自定义图标
  const icon = new BMap.Icon(carIcon, new BMap.Size(32, 32), {
    // 以图标中心为锚点，保证旋转围绕中心
    anchor: new BMap.Size(16, 16),
  });

  // 创建标记并设置图标
  marker.value = new BMap.Marker(startPoint, { icon });
  map.value.addOverlay(marker.value);
  // 初始保持车头朝上
  if (typeof marker.value.setRotation === "function") {
    marker.value.setRotation(0);
  }
  // 为移动标记添加点击事件显示信息窗口
  marker.value.addEventListener("click", () => {
    updateInfoWindow(currentPoint.value, currentPointIndex.value);
  });
};

// 初始化当前绘制路线
const initPolyline = () => {
  // 转换路径点为BMap.Point对象
  const points = [new BMap.Point(pathPoints[0].lng, pathPoints[0].lat)];

  // 创建折线
  polyline.value = new BMap.Polyline(points, {
    strokeColor: "#000",
    strokeWeight: 4,
    strokeOpacity: 1,
    strokeStyle: "solid",
  });

  // 添加折线到地图
  map.value.addOverlay(polyline.value);
};

// 调整地图以显示整个路线
const adjustMapToShowAllRoute = () => {
  if (!map.value || pathPoints.length <= 1) return;

  // 获取所有路径点
  const allPoints = pathPoints.map((point) => new BMap.Point(point.lng, point.lat));

  // 计算这些点的边界范围
  const bounds = new BMap.Bounds(allPoints[0], allPoints[0]);
  allPoints.forEach((point) => bounds.extend(point));

  // 动态获取 padding，使路线不被上方信息框和下方表格遮挡
  map.value.setViewport(bounds, { padding: getViewportPadding() });
};

// 检查点是否在当前视野范围内（原始，无安全区）
const isPointInViewport = (point) => {
  if (!map.value) return false;

  const bmapPoint = new BMap.Point(point.lng, point.lat);
  return map.value.getBounds().containsPoint(bmapPoint);
};

// 新增：动态计算安全区 padding（上、右、下、左），避免被页面顶部信息框与底部表格遮挡
const getViewportPadding = () => {
  // 顶部信息区域高度（.j-top-box 内含上方蓝条与白条）
  const topBox = document.querySelector(".j-top-box");
  const topH = topBox ? Math.round(topBox.getBoundingClientRect().height) : 0;

  // 尝试探测底部表格或底部占位区域（根据项目实际类名可增补选择器）
  const bottomEl =
    document.querySelector(".bottom-table") ||
    document.querySelector(".j-bottom") ||
    document.querySelector(".table-wrapper");
  const bottomH = bottomEl ? Math.round(bottomEl.getBoundingClientRect().height) : 0;

  // 预留一些额外缓冲，防止紧贴遮挡边界
  const extra = 120;
  const side = 30;
  return [topH + extra, side, bottomH + extra, side];
};

// 新增：检查点是否处于“安全可视区域”（扣除顶部与底部安全区）
const isPointInSafeViewport = (point) => {
  if (!map.value) return false;
  const container = document.getElementById("baidu-map");
  const width = container ? container.clientWidth : window.innerWidth;
  const height = container ? container.clientHeight : window.innerHeight;

  const [topPad, rightPad, bottomPad, leftPad] = getViewportPadding();
  const pixel = map.value.pointToPixel(new BMap.Point(point.lng, point.lat));

  return (
    pixel.x >= leftPad &&
    pixel.x <= width - rightPad &&
    pixel.y >= topPad &&
    pixel.y <= height - bottomPad
  );
};

// 调整地图视野以包含所有已绘制的路径
const adjustMapView = () => {
  if (!map.value || currentPointIndex.value <= 0) return;

  // 获取已绘制的路径点
  const visiblePoints = pathPoints
    .slice(0, currentPointIndex.value + 1)
    .map((point) => new BMap.Point(point.lng, point.lat));

  // 计算这些点的边界范围
  const bounds = new BMap.Bounds(visiblePoints[0], visiblePoints[0]);
  visiblePoints.forEach((point) => bounds.extend(point));

  // 使用安全区 padding 调整视图
  map.value.setViewport(bounds, { padding: getViewportPadding() });
};

// 计算两点之间的角度
const calculateAngle = (point1, point2) => {
  const dx = point2.lng - point1.lng;
  const dy = point2.lat - point1.lat;

  // 使用数学坐标系夹角（相对x轴，逆时针为正）
  const angleFromEast = (Math.atan2(dy, dx) * 180) / Math.PI; // [-180,180]

  // 转换为从北开始、顺时针方向的航向角（0-360）
  const heading = (90 - angleFromEast + 360) % 360;

  return heading;
};

// 更新标记方向
const updateMarkerDirection = (index) => {
  if (!marker.value || typeof marker.value.setRotation !== "function") return;
  if (index >= pathPoints.length - 1) return;

  const angle = calculateAngle(pathPoints[index], pathPoints[index + 1]);

  // 将阈值调小，保证方向显示更精确，减少抖动
  if (Math.abs(angle - previousAngle.value) > 1) {
    marker.value.setRotation(angle);
    previousAngle.value = angle;
  }
};

// 开始动画
const startAnimation = () => {
  console.log("开始动画");
  if (isAnimating.value || currentPointIndex.value >= pathPoints.length - 1) return;

  isAnimating.value = true;
  isPaused.value = false;

  // 启动动画循环
  runAnimation();
};

// 继续动画
const resumeAnimation = () => {
  if (!isPaused.value || currentPointIndex.value >= pathPoints.length - 1) return;

  isPaused.value = false;
  runAnimation();
};

// 运行动画
const runAnimation = () => {
  // 清除之前的定时器
  if (animationInterval.value) {
    clearInterval(animationInterval.value);
  }

  // 根据速度计算间隔时间（速度越快，间隔越短）
  const intervalTime = 800 / animationSpeed.value;

  animationInterval.value = setInterval(() => {
    if (currentPointIndex.value >= pathPoints.length - 1) {
      // 动画结束
      clearInterval(animationInterval.value);
      isAnimating.value = false;
      isPaused.value = false;
      isPlay.value = 1;
      return;
    }

    // 移动到下一个点
    currentPointIndex.value++;
    updateMarkerPositionAndPath(true);
  }, intervalTime);
};

// 更新标记位置和路径
const updateMarkerPositionAndPath = (showInfoWindow = false) => {
  const nextPoint = new BMap.Point(
    pathPoints[currentPointIndex.value].lng,
    pathPoints[currentPointIndex.value].lat
  );

  // 移动标记
  marker.value.setPosition(nextPoint);

  // 更新标记方向
  updateMarkerDirection(currentPointIndex.value);

  // 扩展折线
  const currentPath = polyline.value.getPath();
  currentPath.push(nextPoint);
  polyline.value.setPath(currentPath);

  // 使用安全区判断是否需要调整地图
  if (!isPointInSafeViewport(pathPoints[currentPointIndex.value])) {
    adjustMapView();
  }

  // 显示信息窗口
  if (showInfoWindow) {
    updateInfoWindow(pathPoints[currentPointIndex.value], currentPointIndex.value);
  }
};

// 暂停动画
const pauseAnimation = () => {
  if (animationInterval.value) {
    clearInterval(animationInterval.value);
    animationInterval.value = null;
    isPaused.value = true;
  }
};

// 重置动画
const resetAnimation = () => {
  // 清除定时器
  if (animationInterval.value) {
    clearInterval(animationInterval.value);
    animationInterval.value = null;
  }

  // 关闭信息窗口
  closeInfoWindow();

  // 重置状态
  isAnimating.value = false;
  isPaused.value = false;
  currentPointIndex.value = 0;
  previousAngle.value = 0;

  drivingTime.value = trackList.value[0].createTime;

  // 重置标记位置和方向
  const startPoint = new BMap.Point(pathPoints[0].lng, pathPoints[0].lat);
  marker.value.setPosition(startPoint);
  marker.value.setRotation(0);

  // 重置当前绘制路线
  polyline.value.setPath([startPoint]);

  // 调整地图以显示整个路线
  adjustMapToShowAllRoute();

  // 标记地图已准备就绪
  isReady.value = true;

  // 轨迹路线绘制完成后，设置播放状态为1（准备播放）
  isPlay.value = 1;
};

// 处理进度条变化
const handleProgressChange = (e) => {
  const newIndex = parseInt(e.target.value);

  // 如果正在动画，先暂停
  if (isAnimating.value) {
    pauseAnimation();
  }

  // 更新路径
  const newPath = pathPoints
    .slice(0, newIndex + 1)
    .map((point) => new BMap.Point(point.lng, point.lat));
  polyline.value.setPath(newPath);

  // 更新标记位置
  const newPoint = new BMap.Point(pathPoints[newIndex].lng, pathPoints[newIndex].lat);
  marker.value.setPosition(newPoint);

  // 更新标记方向
  updateMarkerDirection(newIndex);

  // 使用安全区判断是否需要调整地图
  if (!isPointInSafeViewport(pathPoints[newIndex])) {
    adjustMapView();
  }

  // 更新当前索引
  currentPointIndex.value = newIndex;

  // 显示当前点信息窗口
  updateInfoWindow(pathPoints[newIndex], newIndex);
};

// 监听速度变化，动态调整动画速度
watch(animationSpeed, (newVal) => {
  if (isAnimating.value && !isPaused.value) {
    runAnimation();
  }
});

// 工具函数：补零
const pad = (n) => (n < 10 ? `0${n}` : `${n}`);
// 格式化日期为 YYYY-MM-DD HH:mm:ss
const formatDateTime = (d) => {
  const y = d.getFullYear();
  const m = pad(d.getMonth() + 1);
  const day = pad(d.getDate());
  const h = pad(d.getHours());
  const mi = pad(d.getMinutes());
  const s = pad(d.getSeconds());
  return `${y}-${m}-${day} ${h}:${mi}:${s}`;
};
// 安全解析字符串为 Date（兼容 Safari）
const toDate = (v) => (v instanceof Date ? v : new Date(String(v).replace(/-/g, "/")));
// 增加月数（自然月逻辑，处理月末）
const addMonths = (date, months) => {
  const d = new Date(date.getTime());
  const day = d.getDate();
  d.setDate(1);
  d.setMonth(d.getMonth() + months);
  const lastDay = new Date(d.getFullYear(), d.getMonth() + 1, 0).getDate();
  d.setDate(Math.min(day, lastDay));
  return d;
};
// 选择器变更：限制最大三个月范围并同步到查询参数
const onRangeChange = (val) => {
  console.log("布局", val);

  if (!val || val.length !== 2) {
    queryParams.value.startTime = "";
    queryParams.value.endTime = "";
    return;
  }
  const [start, end] = val;
  const startDate = toDate(start);
  const endDate = toDate(end);
  const maxEnd = addMonths(startDate, 3);

  if (endDate.getTime() > maxEnd.getTime()) {
    const clipped = formatDateTime(maxEnd);
    dateRange.value = [start, clipped];
    if (typeof ElMessage !== "undefined" && ElMessage) {
      ElMessage.warning("最多可选择三个月范围，已自动调整结束时间");
    }
    queryParams.value.startTime = start;
    queryParams.value.endTime = clipped;
  } else {
    queryParams.value.startTime = start;
    queryParams.value.endTime = end;
  }
};

// 查询
const handleQuery = async () => {
  await getLocusList();
  nextTick(() => {
    initMap();
  });
};

// 组件挂载时初始化地图
onMounted(async () => {
  // 可选：初始化默认时间范围为最近一天
  const now = new Date();
  const yesterday = new Date(now.getTime() - 24 * 60 * 60 * 1000);
  const defaultStart = formatDateTime(yesterday);
  const defaultEnd = formatDateTime(now);
  dateRange.value = [defaultStart, defaultEnd];
  onRangeChange(dateRange.value);

  await getLocusList();
  nextTick(() => {
    initMap();
  });
});
</script>

<style scoped lang="scss">
.map-container {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}
.j-top-box {
  position: absolute;
  width: 100%;
  top: 0;
  z-index: 999;
}
.j-top {
  width: 100%;
  padding: 2px 30px;
  background-color: #e9f0ff;
  box-shadow: 0 8px 10px 2px rgba(0, 0, 0, 0.08);
  display: flex;
  align-items: center;
}
.j-top-left {
  display: flex;
  align-items: center;
  flex: 1;
}
.j-top1-box {
  width: 80%;
  margin-left: 10%;
  border-bottom-left-radius: 30px;
  border-bottom-right-radius: 30px;
  display: flex;
  background-color: #fff;
  box-shadow: 0 8px 10px 2px rgba(0, 0, 0, 0.08);
}

.j-top1 {
  padding: 5px 30px;
  background-color: #fff;
  /* 新增：仅底部圆角 */
  display: flex;
  align-items: center;
  border-bottom-left-radius: 30px;
  border-bottom-right-radius: 30px;
  /* 新增：默认从上淡入（页面加载或显示时） */
  animation: fadeInFromTop 320ms ease-out both;
  flex: 1;
}
/* 新增：触发由下淡出时可添加该类 */
.j-top1-box.j-top1.fade-out {
  animation: fadeOutToBottom 580ms ease-in both;
  position: relative;
}

.btn {
  background-color: #4080ff;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  text-align: center;
  line-height: 30px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.btn:hover {
  background-color: rgba(64, 128, 255, 0.8);
}
/* 动画关键帧 */
@keyframes fadeInFromTop {
  from {
    opacity: 0;
    transform: translateY(-12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes fadeOutToBottom {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(12px);
  }
}
.map {
  width: 100%;
  height: 100%;
}

.control-panel {
  position: absolute;
  top: 220px;
  left: 20px;
  background-color: rgba(255, 255, 255, 0.9);
  border-radius: 10px;
  padding: 15px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 100;
  min-width: 280px;
}

.control-panel h3 {
  margin-top: 0;
  margin-bottom: 15px;
  color: #333;
  font-size: 18px;
  text-align: center;
}

.overview-control {
  margin-bottom: 15px;
}

.overview-btn {
  width: 100%;
  padding: 8px;
  background-color: #9b59b6;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  transition: background-color 0.2s ease;
}

.overview-btn:hover {
  background-color: #8e44ad;
}

.overview-btn:disabled {
  background-color: #bdc3c7;
  cursor: not-allowed;
}

.button-group {
  display: flex;
  gap: 8px;
  margin: 15px 0;
}

.control-btn {
  flex: 1;
  padding: 10px 5px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.start-btn {
  background-color: #2ecc71;
  color: white;
}

.start-btn:hover {
  background-color: #27ae60;
}

.pause-btn {
  background-color: #f39c12;
  color: white;
}

.pause-btn:hover {
  background-color: #e67e22;
}

.resume-btn {
  background-color: #3498db;
  color: white;
}

.resume-btn:hover {
  background-color: #2980b9;
}

.reset-btn {
  background-color: #e74c3c;
  color: white;
}

.reset-btn:hover {
  background-color: #c0392b;
}

.control-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.progress-control,
.speed-control {
  display: flex;
  align-items: center;
  gap: 10px;
}

.progress-slider,
.speed-slider {
  flex-grow: 1;
  height: 6px;
  border-radius: 3px;
  -webkit-appearance: none;
  appearance: none;
  background: #ddd;
  outline: none;
}

.progress-slider::-webkit-slider-thumb,
.speed-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #3498db;
  cursor: pointer;
}

.progress-control span,
.speed-control span {
  min-width: 40px;
  text-align: center;
}
.track-panel {
  background: #fff;
  border-top: 1px solid #e4e7ed;
  transition: transform 0.3s ease;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  min-height: 200px;
  max-height: 600px;
  z-index: 999;
  will-change: height, transform;
  transform: translateZ(0);

  &.hidden {
    transform: translateY(100%) translateZ(0);
  }

  &.resizing {
    transition: none;
    user-select: none;

    * {
      user-select: none;
      pointer-events: none;
    }

    .resize-handle {
      pointer-events: auto;
    }
  }

  .resize-handle {
    height: 6px;
    background: #f5f7fa;
    cursor: ns-resize;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    will-change: background-color;
    transform: translateZ(0);
    transition: background-color 0.2s ease;

    &:hover {
      background: #e6f7ff;
    }

    &::after {
      content: "";
      width: 40px;
      height: 3px;
      background: #c0c4cc;
      border-radius: 2px;
    }
  }

  .track-card {
    height: calc(100% - 6px);
    border: none;
    border-radius: 0;

    :deep(.el-card__header) {
      padding: 12px 16px;
      border-bottom: 1px solid #e4e7ed;

      .card-header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        width: 100%;

        .title {
          font-weight: 600;
          color: #303133;
          font-size: 16px;
        }

        .controls {
          display: flex;
          align-items: center;
          gap: 12px;

          .progress-container {
            display: flex;
            align-items: center;
            gap: 8px;

            .progress-text {
              font-size: 12px;
              color: #909399;
              min-width: 30px;
              text-align: center;
            }
          }
        }
      }
    }

    :deep(.el-card__body) {
      padding: 0;
      height: calc(100% - 60px);

      .track-list {
        height: 100%;

        .el-table {
          height: 100%;

          .el-table__body-wrapper {
            max-height: calc(100% - 40px);
          }
        }
      }
    }
  }
}
.floating-btn {
  position: fixed;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1001;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  border-radius: 50%;
}
</style>
